package com.ant.backstage.config.filter;

import com.alibaba.fastjson.JSON;
import com.ant.backstage.facade.model.Authentication;
import com.google.common.collect.Lists;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @Author zhangyu
 * @Description
 * @Date 16:57 2022/1/14
 * @Param 解析xml文件中的接口权限配置
 * @return
 **/

public class LoadAuthentication {
    private static final Logger logger = LoggerFactory.getLogger(LoadAuthentication.class);

    private static final List<Authentication> auths = Lists.newArrayList();
    private static final String FILE_NAME = "authentication.xml";

    static {
        loadConfigFile();
    }

    private static void loadConfigFile() {
        try {
            URL url = getResource(FILE_NAME);
            if (url != null) {
                String content = IOUtils.toString(url, "UTF-8");
                //创建一个新的字符串
                StringReader read = new StringReader(content);
                //创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
                InputSource source = new InputSource(read);
                //创建一个新的SAXBuilder
                SAXBuilder sb = new SAXBuilder();
                //通过输入源构造一个Document
                Document doc = sb.build(source);
                //取的根元素
                Element root = doc.getRootElement();
                List<Element> elements = root.getChildren("bean");
                for (Element e : elements) {
                    Authentication authentication = new Authentication();
                    String permission = e.getAttributeValue("permission");
                    String role = e.getAttributeValue("role");
                    String type = e.getAttributeValue("type");
                    String roleLogical = e.getAttributeValue("roleLogical");
                    String permissionLogical = e.getAttributeValue("permissionLogical");
                    String urlPrefix = e.getAttributeValue("urlPrefix");
                    String urlSuffix = e.getAttributeValue("urlSuffix");
                    List<String> permissionList = new ArrayList<>();
                    List<String> roleList = new ArrayList<>();
                    List<String> typeList = new ArrayList<>();
                    if (Optional.ofNullable(permission).isPresent()) {
                        permissionList = Arrays.asList(permission.trim().split(","));
                    }
                    if (Optional.ofNullable(role).isPresent()) {
                        roleList = Arrays.asList(role.trim().split(","));
                    }
                    if (Optional.ofNullable(type).isPresent()) {
                        typeList = Arrays.asList(type.trim().split(","));
                    }
                    if (!Optional.ofNullable(roleLogical).isPresent()) {
                        roleLogical = Authentication.LOGICAL_OR;
                    }
                    if (!Optional.ofNullable(permissionLogical).isPresent()) {
                        permissionLogical = Authentication.LOGICAL_OR;
                    }
                    if (!Optional.ofNullable(urlPrefix).isPresent()) {
                        urlPrefix = "N";
                    }
                    if (!Optional.ofNullable(urlSuffix).isPresent()) {
                        urlSuffix = "N";
                    }
                    authentication.setUrl(e.getAttributeValue("url")).setPermission(permissionList)
                            .setPermissionLogical(permissionLogical).setType(typeList).setRole(roleList)
                            .setRoleLogical(roleLogical).setUrlPrefix(urlPrefix).setUrlSuffix(urlSuffix);
                    auths.add(authentication);
                }
                logger.info("接口权限配置加载auths={}", JSON.toJSONString(auths));
            }
        } catch (Exception e) {
            logger.error("[loadConfigFile]加载{}文件失败：", FILE_NAME, e);
        }
    }

    private static URL getResource(String fileName) {
        try {
            URL url = LoadAuthentication.class.getClassLoader().getResource(fileName);
            if (url != null) {
                logger.info("接口权限配置 Load resource [{}] for [this.getClass().getClassLoader()]", url);
                return url;
            } else {
                logger.info("Could not find resource [{}] for [this.getClass().getClassLoader()]", fileName);
            }
            url = Thread.currentThread().getContextClassLoader().getResource(fileName);
            if (url != null) {
                logger.info("接口权限配置 Load resource [{}] for [Thread.currentThread().getContextClassLoader()]", url);
                return url;
            } else {
                logger.info("Could not find resource [{}] for [Thread.currentThread().getContextClassLoader()]", fileName);
            }
        } catch (Exception e) {
            logger.error("加载{}失败：", fileName, e);
        }
        return null;
    }

    public static Authentication getAuthInfo(String url) {
        if (StringUtils.isBlank(url) || auths == null) {
            return null;
        }
        //equalsIgnoreCase() 方法用于将字符串与指定的对象比较，不考虑大小写。
        for (Authentication a : auths) {
            //startsWith() 方法用于检测字符串是否以指定的前缀开始。 endsWith
            if (a.getUrlPrefix().equals("Y")) {
                if (url.startsWith(a.getUrl())) {
                    return a;
                }
            }
            //后缀
            if (a.getUrlSuffix().equals("Y")) {
                if (url.startsWith(a.getUrl())) {
                    return a;
                }
            }
            //精准
            if (url.equals(a.getUrl())) {
                return a;
            }
        }
        return null;
    }

}
